﻿using WinBookKeeping.Models;
using WinBookKeeping.Utility;
using WinBookKeeping.Data;
using System.Speech.Recognition;
using System.Speech.Synthesis;

namespace WinBookKeeping
{
    public partial class FrmExpendManage : Form
    {
        private readonly IBookKeepingRepository _repository;
        private List<ExpendInfo> expendList = new List<ExpendInfo>();
        private int actType = 1;//提交状态 1 新增 2 修改
        private ListViewItem curItem;
        private int selIndex = -1;
        private SpeechRecognitionEngine recognizer;
        private SpeechSynthesizer synthesizer;
        private bool isListening = false;
        private TextBox currentTargetTextBox;

        public FrmExpendManage()
        {
            InitializeComponent();
            _repository = new BookKeepingRepository();
            InitializeSpeechRecognition();
        }

        private void InitializeSpeechRecognition()
        {
            try
            {
                recognizer = new SpeechRecognitionEngine();
                synthesizer = new SpeechSynthesizer();

                var grammar = new GrammarBuilder();
                grammar.AppendDictation();
                recognizer.LoadGrammar(new Grammar(grammar));

                recognizer.SpeechRecognized += Recognizer_SpeechRecognized;
                recognizer.SpeechRecognitionRejected += Recognizer_SpeechRecognitionRejected;

                recognizer.SetInputToDefaultAudioDevice();
            }
            catch (Exception ex)
            {
                MessageHelper.Error("语音识别初始化", $"初始化语音识别失败：{ex.Message}");
            }
        }

        private void Recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            if (e.Result.Confidence > 0.7 && currentTargetTextBox != null)
            {
                string recognizedText = e.Result.Text;
                if (currentTargetTextBox == textMoney)
                {
                    if (decimal.TryParse(recognizedText, out decimal money))
                    {
                        currentTargetTextBox.Text = money.ToString("0.00");
                    }
                }
                else
                {
                    currentTargetTextBox.Text = recognizedText;
                }
                StopVoiceInput();
            }
        }

        private void Recognizer_SpeechRecognitionRejected(object sender, SpeechRecognitionRejectedEventArgs e)
        {
            synthesizer.SpeakAsync("抱歉，我没有听清楚，请重试。");
            StopVoiceInput();
        }

        private void StartVoiceInput(TextBox targetTextBox)
        {
            if (!isListening)
            {
                try
                {
                    currentTargetTextBox = targetTextBox;
                    recognizer.RecognizeAsync(RecognizeMode.Single);
                    isListening = true;
                    synthesizer.SpeakAsync("请说话。");
                }
                catch (Exception ex)
                {
                    MessageHelper.Error("语音输入", $"启动语音输入失败：{ex.Message}");
                }
            }
        }

        private void StopVoiceInput()
        {
            if (isListening)
            {
                recognizer.RecognizeAsyncStop();
                isListening = false;
                currentTargetTextBox = null;
            }
        }

        private void btnVoiceInputMoney_Click(object sender, EventArgs e)
        {
            StartVoiceInput(textMoney);
        }

        private void btnVoiceInputRemark_Click(object sender, EventArgs e)
        {
            StartVoiceInput(textRemark);
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);
            if (recognizer != null)
            {
                recognizer.Dispose();
            }
            if (synthesizer != null)
            {
                synthesizer.Dispose();
            }
        }

        private async void FrmExpendManage_Load(object sender, EventArgs e)
        {
            await LoadExpendList();
            await LoadCboExpendItems();
        }

        private async Task LoadExpendList()
        {
            ListExpend.Items.Clear();
            expendList = await _repository.GetAllExpendituresAsync();

            foreach (ExpendInfo item in expendList)
            {
                ListViewItem li = CreateLvItem(item);
                ListExpend.Items.Add(li);
            }

            if (expendList.Count > 0)
            {
                textRecordId.Text = (expendList.Max(i => i.expendId) + 1).ToString();
            }
            else
            {
                textRecordId.Text = "1";
            }
        }

        private async Task LoadCboExpendItems()
        {
            cboTypes.Items.Clear();
            cboFItems.Items.Clear();
            var items = await CommonHelper.GetItems(2);
            if (items.Count > 0)
            {
                foreach (string item in items)
                {
                    cboTypes.Items.Add(item);
                    cboFItems.Items.Add(item);
                }
                cboFItems.Items.Insert(0, "请选择");
                cboFItems.SelectedIndex = 0;
                cboTypes.SelectedIndex = 0;
            }
        }

        private async void btnOk_Click(object sender, EventArgs e)
        {
            int id = int.Parse(textRecordId.Text.Trim());
            string itemName = cboTypes.Text.Trim();
            string remark = textRemark.Text.Trim();
            decimal money = 0.00M;
            decimal.TryParse(textMoney.Text.Trim(), out money);
            string expendTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

            if (string.IsNullOrEmpty(remark))
            {
                MessageHelper.Error("支出记录提交", "支出记录描述不能为空！");
                textRemark.Focus();
                return;
            }
            if (money < 0)
            {
                MessageHelper.Error("支出记录提交", "支出金额不能小于0！");
                textMoney.Focus();
                return;
            }

            ExpendInfo expendInfo = new ExpendInfo()
            {
                expendId = id,
                ItemName = itemName,
                expendDesp = remark,
                Money = money,
                expendTime = expendTime
            };

            try
            {
                if (actType == 1)
                {
                    await _repository.AddExpenditureAsync(expendInfo);
                    ListExpend.Items.Add(CreateLvItem(expendInfo));
                    expendList.Add(expendInfo);
                }
                else
                {
                    // 获取原始实体
                    var existingExpend = expendList.FirstOrDefault(e => e.expendId == id);
                    if (existingExpend != null)
                    {
                        // 更新属性
                        existingExpend.ItemName = itemName;
                        existingExpend.expendDesp = remark;
                        existingExpend.Money = money;
                        existingExpend.expendTime = expendTime;
                        
                        await _repository.UpdateExpenditureAsync(existingExpend);
                        ListExpend.Items.Insert(selIndex, CreateLvItem(existingExpend));
                        expendList[selIndex] = existingExpend;
                        ListExpend.Items.RemoveAt(selIndex + 1);
                    }
                }
                MessageHelper.Info("支出记录", "保存成功！");
                actType = 1;
                btnOk.Text = "新增";
                await LoadExpendList();
            }
            catch (Exception ex)
            {
                MessageHelper.Error("支出记录", $"保存失败：{ex.Message}");
            }
        }

        private ListViewItem CreateLvItem(ExpendInfo info)
        {
            ListViewItem lv = new ListViewItem();
            lv.Text = info.expendId.ToString();
            lv.SubItems.Add(info.ItemName);
            lv.SubItems.Add(info.expendDesp);
            lv.SubItems.Add("$" + info.Money.ToString("0.00"));
            lv.SubItems.Add(info.expendTime);
            return lv;
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            textRecordId.Text = (expendList.Count > 0 ? expendList.Max(i => i.expendId) + 1 : 1).ToString();
            cboTypes.SelectedIndex = 0;
            textRemark.Text = "";
            textMoney.Text = "";
            if (actType != 1)
            {
                actType = 1;
                btnOk.Text = "新增";
            }
        }

        private void ListExpend_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (ListExpend.SelectedItems.Count > 0)
            {
                var selItem = ListExpend.SelectedItems[0];
                actType = 2;
                curItem = selItem;
                textRecordId.Text = curItem.Text;
                cboTypes.Text = curItem.SubItems[1].Text;
                textRemark.Text = curItem.SubItems[2].Text;
                textMoney.Text = curItem.SubItems[3].Text.Substring(1);
                btnOk.Text = "修改";
                selIndex = ListExpend.SelectedIndices[0];
            }
        }

        private async void btnDelete_Click(object sender, EventArgs e)
        {
            var selList = ListExpend.SelectedItems;
            if (selList.Count > 0)
            {
                DialogResult dr = MessageHelper.Confirm("删除支出记录", "你确定要删除该支出记录信息吗？");
                if (dr == DialogResult.OK)
                {
                    try
                    {
                        foreach (ListViewItem item in selList)
                        {
                            int id = int.Parse(item.Text);
                            await _repository.DeleteExpenditureAsync(id);
                        }
                        await LoadExpendList();
                        MessageHelper.Info("删除支出记录", "删除成功!");
                    }
                    catch (Exception ex)
                    {
                        MessageHelper.Error("删除支出记录", $"删除失败：{ex.Message}");
                    }
                }
            }
        }

        private async void btnFind_Click(object sender, EventArgs e)
        {
            string kremark = textBox1.Text.Trim();
            string fitemName = cboFItems.Text.Trim();
            if (fitemName == "请选择")
                fitemName = "";
            decimal stMoney = 0, etMoney = 0;
            if (!string.IsNullOrEmpty(txtStMoney.Text))
            {
                decimal.TryParse(txtStMoney.Text, out stMoney);
            }
            if (!string.IsNullOrEmpty(txtEdMoney.Text))
            {
                decimal.TryParse(txtEdMoney.Text, out etMoney);
            }
            if (etMoney > 0 && etMoney < stMoney)
            {
                MessageHelper.Error("查询支出记录", "结束范围金额不能小于开始范围金额！");
                txtEdMoney.Focus();
                return;
            }

            try
            {
                var allExpenditures = await _repository.GetAllExpendituresAsync();
                var findList = allExpenditures.AsQueryable();

                if (!string.IsNullOrEmpty(kremark))
                    findList = findList.Where(r => r.expendDesp.Contains(kremark));
                if (!string.IsNullOrEmpty(fitemName))
                    findList = findList.Where(r => r.ItemName == fitemName);
                if (stMoney > 0)
                    findList = findList.Where(r => r.Money >= stMoney);
                if (etMoney > 0)
                    findList = findList.Where(r => r.Money <= etMoney);

                ListExpend.Items.Clear();
                foreach (ExpendInfo item in findList)
                {
                    ListViewItem li = CreateLvItem(item);
                    ListExpend.Items.Add(li);
                }
            }
            catch (Exception ex)
            {
                MessageHelper.Error("查询支出记录", $"查询失败：{ex.Message}");
            }
        }

        private async void btnAllList_Click(object sender, EventArgs e)
        {
            txtEdMoney.Text = "";
            txtStMoney.Text = "";
            cboFItems.SelectedIndex = 0;
            textBox1.Text = "";
            await LoadExpendList();
        }

        private void label16_Click(object sender, EventArgs e)
        {

        }
    }
}
